OPC Studio User's Guide and Reference
OPC UA Application Configuration
Concepts > Development Concepts > Development Advanced Topics > Configuration and Instrumentation > OPC UA Application Configuration
In This Topic

General

OPC Unified Architecture is a rich specification that allows the participating software use different approaches and parameters to achieve their goals. As a result, there is large number of variable settings that can be tweaked to influence the performance, or achieve full interoperability.

OPC Studio for OPC UA attempts to determine many of these setting automatically, and also exposes the most important ones to the developer by means of properties on the various OPC Studio objects.  As long as this approach works well for your application, you do not have to do anything extra to configure the OPC UA application.

For the communication layer of the OPC UA, OPC Studio relies on OPC UA .NET (stack and) SDK code from OPC Foundation. The OPC UA SDK uses an application configuration object with various settings. OPC Studio creates this application configuration object and provides it to the OPC UA .NET SDK. More specifically, it performs following sequence of steps:

  1. OPC Studio determines where to take the initial application configuration from, and constructs it. Normally, the application configuration is constructed using an internal method, with appropriate settings. However, you can also instruct the OPC Studio to use an empty application configuration, or to load the application configuration from an external file. For more information, see Configuration Sources further below.
  2. Specific parts in the application configuration can be modified using configuration property overrides (described further below). This means that you can change the application configuration from your code.
  3. Where necessary, OPC Studio sets certain parts in the application configuration to the values that are necessary for correct functionality. This implies that some values chosen in previous steps may be overwritten, effectively cannot be changed in that way,

If you need to change something in the .NET SDK configuration from your code, the recommended approach is to use the configuration property overrides. This allows you to make targeted changes to specific settings, and is also more likely to remain compatible with future changes to the OPC UA .NET SDK. The other possible approach (with using an external file to supply the entire configuration) should be reserved for special cases that cannot be done otherwise.

Configuration Property Overrides

You can override the value of one or more selected application configuration properties. Such configuration property overrides are specified using the ConfigurationPropertyOverrides Property. For OPC UA client applications, this property is in EasyUAClient.SharedParameters.EngineParameters. For OPC UA server applications, this property is in EasyUAServer.SharedParameters.EngineParameters.

The ConfigurationPropertyOverrides Property contains a dictionary, where the key is the name of the property in the application configuration object (or property "path", in case of nested properties), and the value is the new value you want to give to the specified application configuration property.

Example

.NET

// This example shows how to limit the maximum number of sessions the OPC UA clients can open with the server.
// You can use any OPC UA client, including our Connectivity Explorer and OpcCmd utility, to connect to the server. 
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client, server and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-OPCStudio-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.Engine;
using OpcLabs.EasyOpc.UA.NodeSpace;

namespace UAServerDocExamples.Configuration
{
    class ServerConfiguration
    {
        public static void MaxSessionCount()
        {
            // Get the shared engine parameters object
            EasyUAServerEngineParameters engineParameters = EasyUAServer.SharedParameters.EngineParameters;

            // Set the maximum number of open session to 2.
            // This particular property is documented here:
            // https://www.opclabs.com/files/onlinedocs/UA-.NETStandard/Latest/Browser%20Help/webframe.html#Opc.Ua.Core~Opc.Ua.ServerConfiguration~MaxSessionCount.html
            engineParameters.ConfigurationPropertyOverrides["ServerConfiguration.MaxSessionCount"] = 2;
            
            // Instantiate the server object.
            // By default, the server will run on endpoint URL "opc.tcp://localhost:48040/".
            var server = new EasyUAServer();

            // Define a data variable providing random integers.
            var random = new Random();
            server.Add(new UADataVariable("MyDataVariable").ReadValueFunction(() => random.Next()));

            // Start the server.
            Console.WriteLine("The server is starting...");
            server.Start();

            Console.WriteLine("The server is started.");
            Console.WriteLine();

            // Let the user decide when to stop.
            Console.WriteLine("Press Enter to stop the server...");
            Console.ReadLine();

            // Stop the server.
            Console.WriteLine("The server is stopping...");
            server.Stop();

            Console.WriteLine("The server is stopped.");
        }
    }
}

Application Configuration Properties

The individual application configuration properties are given by the underlying software - in this case, the OPC UA .NET libraries from OPC Foundation. You will need understanding of the OPC UA .NET stack and SDK in order to modify these properties.

For convenience, we have generated a reference documentation for the types used in application configuration. The content of the documentation comes from the libraries themselves.

If you want to override some configuration properties, your starting point will be the ApplicationConfiguration Class. There are properties of this class that hold additional sub-objects for various segments of the application functionality. For example, if you are developing a an OPC UA server, many server-related behaviors will be configured in the ServerConfiguration Property, which holds an instance of the ServerConfiguration Class.

When overriding a nested property, use a dot ('.') to separate the parent and the child. For example, use "ServerConfiguration.MaxSessionCount" to address and override the MaxSessionCount Property in the application configuration.

Configuration Sources

When OPC Studio constructs the initial application configuration, it can consider one or more configuration sources. OPC Studio takes the enabled configuration sources in order, and the first configuration source that is able to provide the application configuration is used. The particular configuration sources are described further below, and are examined in this order:

  1. AppConfig configuration source. This configuration source is enabled when the UAConfigurationSources.AppConfig flag is set.
  2. Internal configuration source. This configuration source is enabled when the UAConfigurationSources.Internal flag is set.
  3. Empty configuration source. This configuration source is enabled when the UAConfigurationSources.Empty flag is set.

It is an error if no configuration source is available.

The flags determining which application configuration sources are enabled are in the ConfigurationSources property. For OPC UA client applications, this property is in EasyUAClient.SharedParameters.EngineParameters. For OPC UA server applications, this property is in EasyUAServer.SharedParameters.EngineParameters.

Empty Configuration Source

You will not normally use this configuration source. This configuration source provides an empty application configuration object. Many settings do not have suitable value in the empty application configuration. Consequently, a useable application configuration can be derived from the empty configuration source by explicitly overriding many properties in your own application, and you will need a detailed knowledge of the application configuration object to do so properly.

Internal Configuration Source

This is the most commonly used configuration source. It provides an application configuration object automatically pre-filled with settings that OPC Studio has determined as appropriate for the application (OPC UA client or OPC UA server). Some of the settings are constant, and some depend on the application and its operating environment.

AppConfig Configuration Source

With this configuration source, the initial application configuration is defined in a separate configuration file. The name or path of the application configuration file can be specified in the "app.config" file for the .NET application; if not specified, it defaults to the name of the application executable, but with a ".config.xml" extension instead.

If, for any reason, you need to change parameters that cannot be influenced using various properties on OPC Studio objects, you can decide to provide the whole set of parameters yourself.  To do so, make sure that the ConfigurationSources property contains the UAConfigurationSources.AppConfig flag set (in the default value setting, this bit is set, together with UAConfigurationSources.Internal).

With this setting on, the whole set of parameters for OPC UA .NET Stack and SDK becomes accessible to you. You can find the description of how to configure the .NET Stack and SDK parameters here: OPC UA .NET SDK Configuration .

When the UAConfigurationSources.Internal flag is set as well, a failure to load the UA configuration from file causes OPC Studio to determine and provide all configuration parameters automatically, which is therefore the default behavior if no UA configuration file is present.

Example

// Shows how to configure the OPC UA .NET stack and SDK using its configuration file (XML). For more information, see
// https://kb.opclabs.com/OPC_UA_.NET_SDK_Configuration .
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using OpcLabs.BaseLib.Instrumentation;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.Engine;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UANetSdkConfiguration
{
    class Program
    {
        static void Main()
        {
            // Set the source of OPC UA .NET SDK configuration to the "App.config" file only. In "old-style" Visual Studio
            // projects (for .NET Framework only), during the build, Visual Studio copies the "App.config" file from the
            // project to the output directory, and renames it to match the name of the executable. In this example, the
            // "App.config" from the project becomes "UANetSdkConfiguration.exe.config" in the build output directory. The
            // runtime looks for this file by appending ".config" to the name of the currently running executable.
            //
            // In "new-style" Visual Studio projects (mainly for .NET Core/.NET 5+), this automatic mechanism is not
            // present. To get around it, simply include a properly named "App.config" file (in our case, it is
            // "UANetSdkConfiguration.dll.config") in the project's root directory, and set "Copy to Output Directory" in
            // its Properties to either "Copy always" or "Copy if newer". Notice the ".dll.config" file extension used
            // under .NET Core/.NET 5+, as opposed to ".exe.config" under .NET Framework.
            // 
            // The "App.config" mechanism is a standard configuration mechanism in .NET Framework. In our case, the
            // "App.config" contains a references to *another* XML configuration file, whose format is specific to the OPC
            // UA .NET SDK. This example calls this file "MyApplication.Config.xml", but it can have any name, as long as it
            // matches the information provided in the (properly renamed) "App.config".
            //
            // The "MyApplication.Config.xml" file in this example specifies somewhat lower value for the MaxMessageSize
            // transport quota than the default.
            //
            // If the "App.config" file does not specify the file path of the OPC UA .NET SDK configuration, the component
            // tries to load it from a default file, residing in the same directory as the application's executable
            // assembly, and with the same name, but with a file extension ".Config.xml". This means that for this project,
            // it would be named UANetSdkConfiguration.Config.xml.

            EasyUAClient.SharedParameters.EngineParameters.ConfigurationSources = UAConfigurationSources.AppConfig;


            // Hook static events.
            // Uncomment the statement below for troubleshooting.
            //EasyUAClient.LogEntry += EasyUAClientOnLogEntry;


            // Perform some OPC operations.

            UAEndpointDescriptor endpointDescriptor =
                "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            // or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
            // or "https://opcua.demo-this.com:51212/UA/SampleServer/"

            // Instantiate the client object
            var client = new EasyUAClient();

            Console.WriteLine("Obtaining value of a node...");
            try
            {
                object value = client.ReadValue(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853");

                // Display results
                Console.WriteLine("value: {0}", value);
            }
            catch (UAException uaException)
            {
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
            }

            Console.WriteLine();
            Console.WriteLine("Press Enter to continue...");
            Console.ReadLine();
        }

        // Event handler for the LogEntry event.
        // Display the loggable entries related to UA .NET SDK configuration.
        private static void EasyUAClientOnLogEntry(object sender, LogEntryEventArgs logEntryEventArgs)
        {
            if ((130 <= logEntryEventArgs.EventId) && (logEntryEventArgs.EventId <= 139))
                Console.WriteLine(logEntryEventArgs);
        }
    }
}

 

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <!-- Define the UAClientEngine configuration section. This part is always the same. -->
  <configSections>
    <section name="UAClientEngine" type="Opc.Ua.ApplicationConfigurationSection,Opc.Ua.Core"/>
  </configSections>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
  </startup>

  <!-- Define the .NET SDK configuration. -->
  <UAClientEngine>
    <ConfigurationLocation xmlns="http://opcfoundation.org/UA/SDK/Configuration.xsd">
      <!-- You can vary the file path and name according to your needs, but you must assure that the referenced file exists
      and contains a valid configuration. If you are including the .NET SDK configurtaion file in your Visual Studio 
      project, do not forget to set "Copy to Output Directory" in its Properties to either "Copy always" or "Copy if newer".
      -->
      <FilePath>MyApplication.Config.xml</FilePath>
    </ConfigurationLocation>
  </UAClientEngine>
</configuration>

 

<?xml version="1.0" encoding="utf-8"?>
<ApplicationConfiguration
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:ua="http://opcfoundation.org/UA/2008/02/Types.xsd"
  xmlns:s1="http://opcfoundation.org/UA/Sample/Configuration.xsd"
  xmlns:s2="http://opcfoundation.org/UA/SDK/COM/Configuration.xsd"
  xmlns="http://opcfoundation.org/UA/SDK/Configuration.xsd"
>
  <!-- A human readable but not necessarily unique name for the application instance -->
  <ApplicationName>Client Application with EasyOPC-UA</ApplicationName>

  <!-- A globally unique identifier for the application instance.
       This is overridden with the value contained in the application certificate. -->
  <ApplicationUri>urn:localhost:OpcLabs:EasyOpc:UA:EasyUAClient</ApplicationUri>

  <!-- A globally unique URI for the product (usually assigned by the product vendor) -->
  <ProductUri>http://www.opclabs.com/QuickOPC-UA</ProductUri>

  <!-- Indicates the type of application (Client, Server or ClientServer). -->
  <ApplicationType>Client_1</ApplicationType>

  <!-- Specifies security related configuration information -->
  <SecurityConfiguration>

    <!-- The certificate store and the location of the application instance certificate in the certificate store -->
    <ApplicationCertificate>

      <!-- The type of store. -->
      <StoreType>Directory</StoreType>

      <!-- The location of the store. 
           Windows store must start with LocalMachine, CurrentUser or CurrentService
           The name of the store is appended.
           Note that the names used in code are difference from what appears in the control panel.
           e.g. My == "Personal", Root == "Trusted Root Certification Authorities" -->
      <StorePath>CommonApplicationData\OPC Foundation\CertificateStores\MachineDefault</StorePath>

      <!-- ReSharper disable once CommentTypo -->
      <!-- The subject for the certificate 
           Note that subject names are complex structures. The text that appears here is the CommonName component.
           A complete distinguished would be something like: 'CN=UA Sample Client, DC=MACHINENAME'
           The first certificate found is used if multiple certificates with the same CommonName exist. 
           The Thumbprint should be specified if the CommonName does not uniquely identify a certificate. -->
      <SubjectName>Client Application with EasyOPC-UA</SubjectName>
      <!-- The SHA1 thumbprint for the certificate.
           The thumbprint uniquely identifies a certificate.
           It should be specified in this file, however, the samples rely on quick and 
           dirty scripts to create new certificate on each machine. A commercial application 
           would generate the initial certificate itself and update the thumbprint accordingly -->
      <!--<Thumbprint>...</Thumbprint>-->
      
    </ApplicationCertificate>

    <!-- The list of certification authorities. 
    
         Typical web browsing applications trust any certificate issued by a CA in the 
         "Trusted Root Certification Authorities" certificate store. However, this approach is 
         not appropriate for UA because Administrators have no control over the CAs that get
         placed in that Root store to facilitate web browsing. This means Administrators must
         specify a different store that is used only for UA related CAs and/or they must explicitly
         specify the certificate for each trusted certification authority. -->
    <TrustedIssuerCertificates>
      <StoreType>Directory</StoreType>
      <StorePath>CommonApplicationData\OPC Foundation\CertificateStores\UA Certificate Authorities</StorePath>
    </TrustedIssuerCertificates>

    <!-- The list of trusted certificates. 
    
         Some UA applications will use self-signed certificates (certificates without a CA)
         which means that every application which communicates with it must be configured to 
         trust it.
         
         Administrators may designate a certificate store that contains trusted UA application 
         instance certificates (this store should not be the same as the store used for CAs 
         certificates). Alternately, Administrators may enter the certificates explicitly in
         this list.
         
         Note that entries in this list may either reference a certificate in the store or
         may contained the entire certificate encoded as base64 data.
         -->
    <!--<TrustedPeerCertificates>
      <StoreType>Windows</StoreType>
      <StorePath>LocalMachine\UA Applications</StorePath>
    </TrustedPeerCertificates>-->
    <TrustedPeerCertificates>
      <StoreType>Directory</StoreType>
      <StorePath>CommonApplicationData\OPC Foundation\CertificateStores\UA Applications</StorePath>
    </TrustedPeerCertificates>
    
    <!-- Applications exchange Nonces during the CreateSession. This value specifies the length. Must be >= 32 -->
    <NonceLength>32</NonceLength>

    <!-- The directory used to store invalid certificates for later review by the administrator. -->
    <RejectedCertificateStore>
      <StoreType>Directory</StoreType>
      <StorePath>CommonApplicationData\OPC Foundation\CertificateStores\RejectedCertificates</StorePath>
    </RejectedCertificateStore>
  
  </SecurityConfiguration>
    
  <!-- Maps different transports onto a .NET implementation of a WCF Binding
  
       WCF bindings are very complex and have many parameters that can be tweaked. To ensure
       interoperability the SDK has defined 3 standard bindings which can be selected with this
       element. Developers may define their own Bindings as well provided the inherit from the 
       Opc.Ua.Binding.BaseBinding type and implement the same constructor as the built-in binding
       provide.
       
       Note protocols other than HTTP or UA-TCP are not considered to be interoperable -->
<TransportConfigurations>
    <!-- This binding wraps the ANSI C implementation of UA-TCP instead of using the C# implementation. -->
    <!--
    <TransportConfiguration>
      <UriScheme>opc.tcp</UriScheme>
      <TypeName>Opc.Ua.NativeStack.NativeStackBinding,Opc.Ua.NativeStackWrapper</TypeName>
    </TransportConfiguration>
    -->

    <!-- This binding uses the WCF binary encoded XML over TCP -->
    <TransportConfiguration>
      <UriScheme>net.tcp</UriScheme>
      <TypeName>Opc.Ua.Bindings.UaSoapXmlOverTcpBinding</TypeName>
    </TransportConfiguration>
    <!--
    -->

    <!-- This binding uses the WCF binary encoded XML over PIPE -->
    <TransportConfiguration>
      <UriScheme>net.pipe</UriScheme>
      <TypeName>Opc.Ua.Bindings.UaSoapXmlOverPipeBinding</TypeName>
    </TransportConfiguration>
    <!--
    -->

  </TransportConfigurations>

  <!-- Specifies quotas used to by the transport layer -->
  <TransportQuotas>
    
    <!-- The default timeout in milliseconds for operations (used by clients) -->
    <OperationTimeout>120000</OperationTimeout>
    
    <!-- The maximum length for a string value in any message -->
    <MaxStringLength>1048576</MaxStringLength>
    
    <!-- The maximum length for a byte string value in any message -->
    <MaxByteStringLength>4194304  </MaxByteStringLength>
    
    <!-- The maximum length for any array in a message. 
         Note that some protocols do not distinguish between bytes and arrays. 
         In these cases the binding will choose the larger of 
         MaxByteStringLength or MaxArrayLength-->
    <MaxArrayLength>655350</MaxArrayLength>
    
    <!-- The maximum size of any message -->
    <!-- Made the maximum message size shorter for the purpose of the example. -->
    <MaxMessageSize>4000000</MaxMessageSize>
    
    <!-- The maximum buffer size 
         This value controls how big a block of memory the transport layer allocates.
         Setting this value to a large value will reduce performance and use a lot of RAM -->
    <!-- 
      Changed from 65535 to 65536 for better coping with a buggy server that had messages longer (by one byte) than 
      negotiated with encrypted connections, when less than 65536 bytes were requested. -->
    <!-- Source correlation: {A385F93F-5D0D-45EC-BE2A-A7B7F5F7F96B} -->
    <MaxBufferSize>65536</MaxBufferSize>
    
    <!-- The lifetime of a SecureChannel in milliseconds.
         This specifies how long the server will keep a broken channel around while waiting 
         for a client to reconnect.
         Not used by HTTP or .NET TCP bindings -->
    <ChannelLifetime>300000</ChannelLifetime>
    
    <!-- The lifetime of a SecurityToken in milliseconds.
         This specifies how long a security token can be used without renewal. -->
    <SecurityTokenLifetime>3600000</SecurityTokenLifetime>
  </TransportQuotas>

  <!-- This element is only required for Client and ClientServer applications -->
  <ClientConfiguration>
    <!-- The default timeout for new sessions -->
    <DefaultSessionTimeout>60000</DefaultSessionTimeout>
    
    <!-- The well-known URLs for the local discovery servers
         URLs are tested in the order they appear in this list. -->
    <WellKnownDiscoveryUrls>
      <ua:String>opc.tcp://{0}:4840</ua:String>
      <ua:String>http://{0}:52601/UADiscovery</ua:String>
      <ua:String>http://{0}/UADiscovery/Default.svc</ua:String>
    </WellKnownDiscoveryUrls>
    
    <!-- EndpointDescriptions for system wide discovery servers -->
    <DiscoveryServers></DiscoveryServers>
    
    <!-- The file used to save the EndpointDescriptions for servers known to the Client -->
    <EndpointCacheFilePath>OpcLabs.EasyOpc.UA.EasyUAClient.Endpoints.xml</EndpointCacheFilePath>

      <!-- The minimum subscription lifetime.
      This ensures subscriptions are not set to expire too quickly. The requested lifetime count
      and keep alive count are calculated using this value and the request publishing interval -->
      <MinSubscriptionLifetime>10000</MinSubscriptionLifetime>
  </ClientConfiguration>

  <Extensions>
  </Extensions>
  
  <!--
  Masks supported by the trace feature. 
  Servers will detect changes within 5 seconds.
  
  Do not output any messages.
  None = 0x0;

  Output error messages.
  Error = 0x1;

  Output informational messages.
  Information = 0x2;

  Output stack traces.
  StackTrace = 0x4;

  Output basic messages for service calls.
  Service = 0x8;

  Output detailed messages for service calls.
  ServiceDetail = 0x10;

  Output basic messages for each operation.
  Operation = 0x20;

  Output detailed messages for each operation.
  OperationDetail = 0x40;

  Output messages related to application initialization or shutdown
  StartStop = 0x80;

  Output messages related to a call to an external system.
  ExternalSystem = 0x100;

  Output messages related to security
  Security = 0x200;
  -->

  <TraceConfiguration>
    <OutputFilePath>LocalApplicationData\OPC Labs\Logs\EasyUAClient.log.txt</OutputFilePath>
    <DeleteOnLoad>true</DeleteOnLoad>
    <!-- Show Only Errors -->
    <!-- <TraceMasks>1</TraceMasks> -->
    <!-- Show Only Security and Errors -->
    <!-- <TraceMasks>513</TraceMasks> -->
    <!-- Show Only Security, Errors and Trace -->
    <TraceMasks>515</TraceMasks>
    <!-- Show Only Security, COM Calls, Errors and Trace -->
    <!-- <TraceMasks>771</TraceMasks> -->
    <!-- Show Only Security, Service Calls, Errors and Trace -->
    <!-- <TraceMasks>523</TraceMasks> -->
    <!-- Show Only Security, ServiceResultExceptions, Errors and Trace -->
    <!-- <TraceMasks>519</TraceMasks> -->
  </TraceConfiguration>

  <!-- Enables the hi-res clock for the process to allows for shorter (<100ms) publishing and sampling intervals. -->
  <!-- QueryPerformanceCounter does not work on all multi-core machines so enabling the hi-res clock by default is not recommended. -->
  <DisableHiResClock>true</DisableHiResClock>
  
</ApplicationConfiguration>

 

 

See Also

Knowledge Base

Examples - Client Instrumentation